//
// Created on 2024/11/18.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef HRIME_CANGJIE_CODE_TABLE_H
#define HRIME_CANGJIE_CODE_TABLE_H

#include <cstddef>
#include <string>
#include <vector>

// store all candidates with same code
struct CodeGroup {
    std::vector<std::string> chars;
};

class CangjieCodeTable {
public:
    static constexpr std::size_t ALPHABET_MAX = 27;
    static constexpr std::size_t CANGJIE_LENGTH_MAX = 5;
    using WordToCodeMap = std::unordered_map<std::string, std::string>;

public:
    static CangjieCodeTable &Instance(void)
    {
        static CangjieCodeTable instance;
        return instance;
    }
    CangjieCodeTable(void);
    void SetCodeTablePath(std::string const &path) { this->codeTablePath_ = path; }
    void SetWordDictPath(std::string const &path);
    bool LoadFromCodeTable(std::string const &path);
    bool LoadFromWordDict(std::string const &path);
    std::string Deploy(std::string const &fileDir);
    std::string CodeToChar(std::string const &code) const;
    std::string Load(std::string const &fileDir);
    std::string LoadFromCodeTableBuffer(std::string const &buffer);
    std::string LoadFromWordDictBuffer(std::string const &buffer);
    std::vector<std::string> GetCandidates(std::string const &code) const;
    
private:
    static std::size_t CodeToIndex(std::string code);
    static std::string WordToCode(WordToCodeMap &wordToCode, std::string const &word);
    std::string LoadCodeTable(std::string const &fileDir);
    
private:
    std::string codeTablePath_;
    std::string wordDictPath_;
    std::vector<CodeGroup> codeToChar_;
    WordToCodeMap wordToCode_;
    std::vector<char *> charToCode_;
};

#endif //HRIME_CANGJIE_CODE_TABLE_H
